package SS10W_TI3_PR2_Praktikum.a11.copy;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * Praktikum: P2P<br>
 * Semester: WS10<br>
 * Aufgaben-Nr.: 11<br>
 * 
 * Version: V1<br>
 * Aenderungen:
 * 
 * Quellen: API, Wikipedia
 *
 *  
 * @author Mueller-Pettenpohl, Tell #1989982, Rumpf, Soeren #1971654<br><br>
 * 
 */

public class MessageServer implements Runnable {
    static int count = 0;
    Socket connectionSocket;
    String clientSentence;
    String modifiedSentence;
    States s;
    Reaction r;
    boolean run = true;
    boolean sysrun = true;
    BufferedReader inFromClient = null;
    DataOutputStream outToClient = null;

    public MessageServer(Socket clientConnection) {
        this.connectionSocket = clientConnection;
        s = States.REGULAR;
        r = Reaction.NONE;
    }

    private void regular() {
        String s = clientSentence.toUpperCase() + '\n';
        this.r = Reaction.NONE;
        System.out.println("In regular();");
        try {
            outToClient.writeBytes(s);
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void busy() {
        String s = "Server is busy." + '\n';
        this.r = Reaction.NONE;
        System.out.println("In busy();");
        try {
            outToClient.writeBytes(s);
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void hacked() {
        String s = clientSentence.replace("a", "xXx").toString()+ '\n';
        System.out.println("In hacked();");
        int result = 1 + (int) (Math.random() * (3 - 1) + 0.5);
        switch (result) {
            case 1:
                this.r = Reaction.ECHO;
                // echo();
            case 2:
                this.r = Reaction.REVERSE;
                // reverse();
            case 3:
                this.r = Reaction.LOL;
                // lol();
                break;

            default:
                break;
        }
        try {
            outToClient.writeBytes(s);
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void echo() {
        String s = clientSentence+ '\n';
        System.out.println("In echo();");
        try {
            outToClient.writeBytes(s);
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.r = Reaction.REVERSE;
        // reverse();
    }

    private void reverse() {
        String s = new StringBuffer(clientSentence).reverse().toString()+ '\n';
        System.out.println("In reverse();");
        try {
            outToClient.writeBytes(s);
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.r = Reaction.LOL;
        // lol();
    }

    private void lol() {
        char[] consonants = new char[] { 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's',
                't', 'v', 'w', 'x', 'y', 'z' };
        String s = clientSentence.toLowerCase()+ '\n';
        System.out.println("In lol();");
        System.out.println("Substring: " + s.substring(0, 3));
        char work;
        for (int i = 0; i < s.length(); i++) {
            work = s.charAt(i);
            boolean match = false;
            for (int j = 0; j < consonants.length; j++) {
                if (work == consonants[j]) {
                    match = true;
                }
            }
            if (match) {
                String sub1 = s.substring(0, i);
                String sub2 = s.charAt(i) + "o" + s.charAt(i);
                String sub3 = s.substring(i + 1, s.length());
                s = sub1 + sub2 + sub3+ '\n';
                i += 2;
            }

        }
        try {
            outToClient.writeBytes(s);
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (this.s == States.REGULAR) {
            this.r = Reaction.ECHO;
            // echo();
        }else if (this.s == States.HACKED) {
            int result = 1 + (int) (Math.random() * (3 - 1) + 0.5);
            switch (result) {
                case 1:
                    this.r = Reaction.ECHO;
                    // echo();
                case 2:
                    this.r = Reaction.REVERSE;
                    // reverse();
                case 3:
                    this.r = Reaction.LOL;
                    // lol();
                    break;

                default:
                    break;
            }
        }
    }

    public void run() {
        try {
            inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            sysrun = false;
            System.out.println("inFromClient caused Exception");
        }

        try {
            outToClient = new DataOutputStream(connectionSocket.getOutputStream());
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            sysrun = false;
            System.out.println("outToClient caused Exception");
        }
        do {
            // Wait for incoming messages from client

            // Open Servers outputstream
            System.out.println("Run() Durchlauf Nr. : "  + ++count);

            try {
                if ((clientSentence = inFromClient.readLine()) != null) {
                    if (clientSentence == "$null") {
                        run = false;
                        sysrun = false;
                    }
                    // if(clientSentence.contains("busy")){
                    // s = States.BUSY;
                    // }
                }
            }catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                sysrun = false;
                System.out.println("inFromClient.readLine() caused Exception");
            }

            if (clientSentence == null || connectionSocket.isClosed() && !sysrun) {
                System.out.println("Client closed connection");
                run = false;
                connectionSocket = null;
            }else {
                System.out.println("Received: " + clientSentence);
                if (clientSentence.startsWith("/state")) {
                    System.out.println("In starts with: ");
                    String sub = clientSentence.substring(7);
                    sub = sub.toLowerCase();
                    if (sub.startsWith("regular")) {
                        System.out.println("Identified regular:");
                        this.s = States.REGULAR;
                        String sub2 = clientSentence.substring(14) + '\n';
                        clientSentence = sub2;
                    }else if (sub.startsWith("busy")) {
                        System.out.println("Identified busy:");
                        this.s = States.BUSY;
                        String sub2 = clientSentence.substring(11) + '\n';
                        clientSentence = sub2;
                    }else if (sub.startsWith("hacked")) {
                        System.out.println("Identified hacked:");
                        this.s = States.HACKED;
                        String sub2 = clientSentence.substring(13) + '\n';
                        clientSentence = sub2;
                    }
                }else{
                    
                    // State unterscheidung mit switch case
                    switch (this.s) {
                        case REGULAR:
                            regular();
                            break;
                        case BUSY:
                            busy();
                            break;
                        case HACKED:
                            hacked();
                            break;
                        default:
                            break;
                    }

                    switch (r) {
                        case ECHO:
                            echo();
                            break;
                        case REVERSE:
                            reverse();
                            break;
                        case LOL:
                            lol();
                            break;
                        default:
                            break;
                    }
                }
                
                System.out.println("Server State: " + s.toString());
                run = true;
            }// else
        }while (run && sysrun);
        System.out.printf("MessageServer terminating");
        for (int i = 0; i < 3; i++) {
            try {
                Thread.sleep(500);
                System.out.printf(".");
            }catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.printf("\n");
    }// run
}// MessageServer
